const path = require('path')
const fs = require('fs');
const { promisify } = require('util')

const { validate } = require('schema-utils');
const globby = require('globby');
const schema = require('./schema.json');
const webpack = require('webpack');
const { RawSource } = webpack.sources;
const readFile = promisify(fs.readFile);
class CopyWebpackPlugin {
  constructor(options) {
    // 验证options是否符合规范

    validate(schema, options, {
      name: 'CopyWebpackPlugin'
    })
    this.options = options
  }

  apply(compiler) {
    // 初始化compilation
    compiler.hooks.thisCompilation.tap('CopyWebpackPlugin', (compilation) => {
      // 添加资源hooks
      compilation.hooks.additionalAssets.tapAsync('CopyWebpackPlugin', async cb => {
        // 将from中资源复制到to中，输出出去


        const { from, to = '.', ignore } = this.options;
        // context就是webpack配置
        // 运行指令的目录
        const context = compiler.options.context; // process.cwd()
        // 将输入路径变成绝对路径
        const absoluteFrom = path.isAbsolute(from) ? from : path.resolve(from);

        // 1.过滤掉ignore的文件
        // globby要处理的文件夹,options
        const paths = await globby(absoluteFrom, { ignore });
        console.log(paths); //所有要加载的资源路径数组

        // 2.读取from中的所有资源
        const files = await Promise.all(
          paths.map(async (absolutePath) => {
            // 读取文件
            const data = await readFile(absolutePath);
            // 文件名称
            const relativePath = path.basename(absolutePath)
            // 和to属性结合
            // reset.css => css/reset.css
            const fileName = path.join(to, relativePath);
            return {
              // 文件数据
              data,
              fileName
            }
          })
        )

        // 3.生成webpack格式的资源
        const assets = files.map(file => {
          const source = new RawSource(file.data);
          return {
            source,
            filename: file.fileName
          }
        })
        // 4.添加compilation中，输出出去
        assets.forEach((asset) => {
          compilation.emitAsset(asset.filename, asset.source)
        })
        cb();
      })
    })
  }
}

module.exports = CopyWebpackPlugin;